package com.boe.csb.core.common.utils;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.boe.csb.core.common.exception.CSBErrorCode;
import com.boe.csb.core.common.exception.CSBException;

public class PublishParamChecker {
	
	private static List<String> methodList = new ArrayList<String>();
	
	private static List<String> provideTypeList = new ArrayList<String>();
	
	private static List<Integer> ottFlagList = new ArrayList<Integer>();
	
	private static List<String> paramTypeList = new ArrayList<String>();
	
	private static List<Integer> mapStyleList = new ArrayList<Integer>();
	
	private static List<String> extTypeList = new ArrayList<String>();
	
	private static List<String> reqFormatList = new ArrayList<String>();
	
	private static List<String> responseFormatList = new ArrayList<String>();
	
	static{
		methodList.add("GET");
		methodList.add("POST");
		methodList.add("DELETE");
		methodList.add("PUT");
		
		provideTypeList.add("Restful");
		provideTypeList.add("HSF");
		provideTypeList.add("WebService");
		provideTypeList.add("DUBBO");
		provideTypeList.add("HOH");
		
		ottFlagList.add(0);//透传
		ottFlagList.add(1);//不透传
		
		paramTypeList.add("java.lang.String");
		paramTypeList.add("java.lang.Boolean");
		paramTypeList.add("java.lang.Double");
		paramTypeList.add("java.lang.Float");
		paramTypeList.add("java.lang.Long");
		paramTypeList.add("java.lang.Integer");
		paramTypeList.add("java.lang.Short");
		paramTypeList.add("java.lang.Byte");
		
		mapStyleList.add(0);//平台参数
		mapStyleList.add(1);//API参数
		mapStyleList.add(2);//不可见
		
		extTypeList.add("0");//正常
		extTypeList.add("1");//数组
		extTypeList.add("2");//列表
		extTypeList.add("3");//集合set
		
		reqFormatList.add("HTTP");
		reqFormatList.add("JSON");
		
		responseFormatList.add("passThrough");
	}
	
	/**
     * 校验发布服务的信息
     * @param jsonObject
     * @return
     */
    public static boolean checkJson(JSONObject jsonObject){
       	
    	String alias = jsonObject.getString("alias");
    	if(StringUtils.isEmpty(alias)){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, "别名不能为空");
    	}
    	
    	String serviceName = jsonObject.getString("serviceName");
    	if(StringUtils.isEmpty(serviceName)){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, "服务全名不能为空");
    	}
    	
    	checkOttFlag(jsonObject);
    	checkConsumeType(jsonObject);
    	
    	String provideType = jsonObject.getString("provideType");
    	if(provideType == null || !provideTypeList.contains(provideType)){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, "接入协议参数不合法");
    	}
    	    	
    	JSONArray errList = jsonObject.getJSONArray("errList");
    	JSONObject accessEndpointJSON = jsonObject.getJSONObject("accessEndpointJSON");
    	
    	if(provideType.equalsIgnoreCase("Restful")){
    		checkRestFul(accessEndpointJSON);
    	}else if(provideType.equalsIgnoreCase("WebService")){
    		checkWebService(accessEndpointJSON);
    	}else{
    		throw new CSBException(CSBErrorCode.PARAM_ERR, "暂时不支持该接入协议类型");
    	}
    	
    	Integer categoryId = jsonObject.getInteger("categoryId");//二级目录
    	if(categoryId == null){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, "请选择二级类目");
    	}
    	
    	JSONArray outputParamList = jsonObject.getJSONArray("outputParamList");
    	JSONArray inputParamList = jsonObject.getJSONArray("inputParamList");
    	for(Object outParam : outputParamList){
    		checkParam((JSONObject)outParam, "输出参数:");
    	}
    	
    	for(Object inParam : inputParamList){
    		checkParam((JSONObject)inParam, "输入参数");
    	}
    	
    	for(Object errParam : errList){
    		checkErrParam((JSONObject)errParam);
    	}
    			
    	return true;
    }
    
    private static boolean checkConsumeType(JSONObject jsonObject){
    	JSONArray consumeTypes = jsonObject.getJSONArray("consumeTypes");
    	if(consumeTypes == null || consumeTypes.size() < 1){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, "开发协议必填");
    	}
    	
    	return true;
    }
    
    private static boolean checkOttFlag(JSONObject jsonObject){
    	int ottFlag = jsonObject.getIntValue("ottFlag");
    	if(!ottFlagList.contains(ottFlag)){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, "响应格式参数不合法");
    	}
    	return true;
    }
    
    /**
     * 校验输入/输出参数
     * 10个参数
     * @param jsonObject
	 * @param preStr 提示前缀
     * @return
     */
    private static boolean checkParam(JSONObject jsonObject, String preStr){
    	String originalName = jsonObject.getString("originalName");
    	if(originalName == null || StringUtils.isEmpty(originalName)){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, preStr + "<originalName>不能为空");
    	}
    	
    	String paramType = jsonObject.getString("paramType");
    	if(paramType == null){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, preStr + "<paramType>类型非法");
    	}
    	
    	String targetName = jsonObject.getString("targetName");
    	if(targetName == null || StringUtils.isEmpty(targetName)){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, preStr + "<targetName>不能为空");
    	}
    	
    	Boolean optional = jsonObject.getBoolean("optional");
    	if(optional == null){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, preStr + "<optional>不能为空");
    	}
    	
    	Integer mapStyle = jsonObject.getInteger("mapStyle");
    	if(mapStyle == null || !mapStyleList.contains(mapStyle)){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, preStr + "<mapStyle>不合法");
    	}
    	
    	String extType = jsonObject.getString("extType");
    	if(extType == null || !extTypeList.contains(extType)){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, preStr + "<extType>不合法");
    	}
    	
    	String passMethod = jsonObject.getString("passMethod");
    	if(passMethod == null || !methodList.contains(passMethod)){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, preStr + "<passMethod>不合法");
    	}
    	
    	return true;
    }
    
    private static boolean checkErrParam(JSONObject jsonObject){
    	
    	/*
    	Long serverId = jsonObject.getLong("serviceId");
    	if(serverId == null){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, "错误码关联的服务ID不能为空");
    	}*/
    	
    	String errCode = jsonObject.getString("errCode");
    	if(errCode == null){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, "错误码不能为空");
    	}
    	
    	String errDesc = jsonObject.getString("errDesc");
    	if(errDesc == null){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, "错误码描述不能为空");
    	}
    	
    	return true;
    }
    
    private static boolean checkRestFul(JSONObject jsonObject){
    	String method = jsonObject.getString("method");
    	if(method == null || !method.contains(method)){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, "方法类型不合法");
    	}
    	
    	String endpoint = jsonObject.getString("endpoint");
    	if(StringUtils.isEmpty(endpoint)){//FIXME
    		throw new CSBException(CSBErrorCode.PARAM_ERR, "端点参数不能为空");
    	}
    	
    	String requestFormat = jsonObject.getString("requestFormat");
    	if(requestFormat == null || !reqFormatList.contains(requestFormat)){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, "请求格式参数非法");
    	}
    	
    	String responseFormat = jsonObject.getString("responseFormat");
    	if(responseFormat == null || !responseFormatList.contains(responseFormat)){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, "响应格式参数非法");
    	}
    	
    	return true;
    }
    
    private static boolean checkWebService(JSONObject jsonObject){
    	
    	String namespace = jsonObject.getString("namespace");
    	String serviceName = jsonObject.getString("serviceName");
    	String endpoint = jsonObject.getString("endpoint");
    	String bindingName = jsonObject.getString("bindingName");
    	String portName = jsonObject.getString("portName");
    	String methodName = jsonObject.getString("methodName");
    	
    	if(StringUtils.isEmpty(endpoint)){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, "端点不能为空");
    	}
    	
    	if(StringUtils.isEmpty(namespace)){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, "命名空间不能为空");
    	}
    	
    	if(StringUtils.isEmpty(serviceName)){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, "service名称不能为空");
    	}
    	
    	if(StringUtils.isEmpty(bindingName)){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, "Binding 名称不能为空");
    	}
    	
    	if(StringUtils.isEmpty(portName)){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, "Port 名称不能为空");
    	}
    	
    	if(StringUtils.isEmpty(methodName)){
    		throw new CSBException(CSBErrorCode.PARAM_ERR, "方法名称不能为空");
    	}
    	
    	return true;
    }


}
